#include "SafQue.hpp"

#define PTHREAD_SIZE 3 

Safqueue que;

void* Pro_Start(void* arg)
{
    int id = *((int*) arg);
    int val = 0;
    while(val <= 100){
        que.Push(val, id);
        //原因见下
        //printf("i am producer %d, i produce %d\n", id, val); 
        val++;
    }
    return NULL;
}

void* Cons_Start(void* arg)
{
    int id = *((int*) arg);
    while(1){
        /*
         ret = que.Front
         踩坑记录(详情见hpp文件)：消费者与消费者的互斥没有做完全，当时在做取队首操作的时候忘记进行消费者加锁的保护了，最终导致程序出现二异性
        */
        //在打印时会发现有时东西没有生产出来，就消费了，原因是没有保证打印的原子性，在即将打印前，时间片到了，被换出了，在下次恢复现场后再打印
       // printf("i am consumer %d, i consume %d\n", id, ret);
        int ret = que.Front();
        que.Pop(id);
        if(ret >= 100){
            break;
        }
    }
    return NULL;
}

int main()
{
    que.init();
    pthread_t pro[PTHREAD_SIZE];
    pthread_t cons[PTHREAD_SIZE];
    for(int i = 0;  i < PTHREAD_SIZE; ++i){
        int* tmp = new int(i+1);
        int ret = pthread_create(&pro[i], NULL, Pro_Start, tmp);
        if(ret != 0){
            perror("pthread_create");
            return 0;
        }
        
        ret = pthread_create(&cons[i], NULL, Cons_Start, tmp);
        if(ret != 0){
            perror("pthread_create");
            return 0;
        }
    }

    for(int i = 0; i < PTHREAD_SIZE; ++i){
            pthread_join(pro[i], NULL);
            pthread_join(cons[i], NULL);
    }
    return 0;
}
